﻿
using Sys;
using System.Silverlight;
using System.Silverlight.Presentation;
using System.Silverlight.Presentation.Animation;

namespace SBT
{
    public class Button : AgBehavior
    {
        string m_mouseEnterName;
        public string MouseEnterAnimName 
        { 
            get { return m_mouseEnterName; }
            set 
            {
                if (value != m_mouseEnterName)
                {

                    if (IsInitialized)
                    {
                        try
                        {
                            m_mouseEnterAnim = (Storyboard)Element.FindName(value);
                            m_mouseEnterName = value;
                        }
                        catch
                        {
                            Debug.Trace("MouseEnterAnimName_set failed");
                        }
                    }
                    else
                    {
                        m_mouseEnterName = value;
                    }
                }
            }
        }
        string m_mouseLeaveName;
        public string MouseLeaveAnimName
        {
            get { return m_mouseLeaveName; }
            set
            {
                if (value != m_mouseLeaveName)
                {

                    if (IsInitialized)
                    {
                        try
                        {
                            m_mouseLeaveAnim = (Storyboard)Element.FindName(value);
                            m_mouseLeaveName = value;
                        }
                        catch
                        {
                            Debug.Trace("MouseLeaveAnimName_set failed");
                        }
                    }
                    else
                    {
                        m_mouseLeaveName = value;
                    }
                }
            }
        }
        string m_mouseDownName;
        public string MouseDownAnimName 
        { 
            get { return m_mouseDownName; }
            set
            {
                if (value != m_mouseDownName)
                {

                    if (IsInitialized)
                    {
                        try
                        {
                            m_mouseDownAnim = (Storyboard)Element.FindName(value);
                            m_mouseDownName = value;
                        }
                        catch
                        {
                            Debug.Trace("MouseDownAnimName_set failed");
                        }
                    }
                    else
                    {
                        m_mouseDownName = value;
                    }
                }
            }
        }
        string m_mouseUpName;
        public string MouseUpAnimName 
        { 
            get { return m_mouseUpName; }
            set
            {
                if (value != m_mouseUpName)
                {

                    if (IsInitialized)
                    {
                        try
                        {
                            m_mouseUpAnim = (Storyboard)Element.FindName(value);
                            m_mouseUpName = value;
                        }
                        catch
                        {
                            Debug.Trace("MouseUpAnimName_set failed");
                        }
                    }
                    else
                    {
                        m_mouseUpName = value;
                    }
                }
            }
        }

        string m_mouseEnterTemplate;

        /// <summary>
        /// Template difining the the Mouse Enter animation. Must be a xaml storyboard. occurences of $targetname$ in the string will be replaced by the name of the button element. 
        /// occurences of $name$ in the string will be replaced by the generated name of the storyboard
        /// </summary>
        public string MouseEnterTemplate
        {
            get { return m_mouseEnterTemplate; }
            set
            {
                if (value != m_mouseEnterTemplate)
                {
                    if (IsInitialized)
                    {
                        try
                        {
                            string workingString = value;
                            while (workingString.IndexOf("$targetname$") != -1)
                            {
                                workingString = workingString.Replace("$targetname$", this.Element.Name);
                            }
                            string genName = GenerateName(Plugin);
                            while (workingString.IndexOf("$name$") != -1)
                            {
                                workingString = workingString.Replace("$name$", genName);
                            }
                            m_mouseEnterAnim = (Storyboard) Plugin.Content.CreateFromXaml(workingString);
                            m_mouseEnterTemplate = value;
                            Element.Resources.Add(m_mouseEnterAnim);
                        }
                        catch
                        {
                            Debug.Trace("MouseEnterTemplate_set failed");
                        }
                    }
                    else
                    {
                        m_mouseEnterTemplate = value;
                    }
                }
            }
        }
        string m_mouseLeaveTemplate;

        /// <summary>
        /// Template difining the the Mouse Leave animation. Must be a xaml storyboard. occurences of $targetname$ in the string will be replaced by the name of the button element. 
        /// occurences of $name$ in the string will be replaced by the generated name of the storyboard
        /// </summary>
        public string MouseLeaveTemplate
        {
            get { return m_mouseLeaveTemplate; }
            set
            {
                if (value != m_mouseLeaveTemplate)
                {
                    if (IsInitialized)
                    {
                        try
                        {
                            string workingString = value;
                            while (workingString.IndexOf("$targetname$") != -1)
                            {
                                workingString = workingString.Replace("$targetname$", this.Element.Name);
                            }
                            string genName = GenerateName(Plugin);
                            while (workingString.IndexOf("$name$") != -1)
                            {
                                workingString = workingString.Replace("$name$", genName);
                            }
                            m_mouseLeaveAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                            m_mouseLeaveTemplate = value;
                            Element.Resources.Add(m_mouseLeaveAnim);
                        }
                        catch
                        {
                            Debug.Trace("MouseLeaveTemplate_set failed");
                        }
                    }
                    else
                    {
                        m_mouseLeaveTemplate = value;
                    }
                }
            }
        }

        string m_mouseDownTemplate;

        /// <summary>
        /// Template difining the the Mouse Down animation. Must be a xaml storyboard. occurences of $targetname$ in the string will be replaced by the name of the button element. 
        /// occurences of $name$ in the string will be replaced by the generated name of the storyboard
        /// </summary>
        public string MouseDownTemplate
        {
            get { return m_mouseLeaveTemplate; }
            set
            {
                if (value != m_mouseDownTemplate)
                {
                    if (IsInitialized)
                    {
                        try
                        {
                            string workingString = value;
                            while (workingString.IndexOf("$targetname$") != -1)
                            {
                                workingString = workingString.Replace("$targetname$", this.Element.Name);
                            }
                            string genName = GenerateName(Plugin);
                            while (workingString.IndexOf("$name$") != -1)
                            {
                                workingString = workingString.Replace("$name$", genName);
                            }
                            m_mouseDownAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                            m_mouseDownTemplate = value;
                            Element.Resources.Add(m_mouseDownAnim);
                        }
                        catch
                        {
                            Debug.Trace("MouseDownTemplate_set failed");
                        }
                    }
                    else
                    {
                        m_mouseDownTemplate = value;
                    }
                }
            }
        }

        string m_mouseUpTemplate;

        /// <summary>
        /// Template difining the the Mouse Up animation. Must be a xaml storyboard. occurences of $targetname$ in the string will be replaced by the name of the button element. 
        /// occurences of $name$ in the string will be replaced by the generated name of the storyboard
        /// </summary>
        public string MouseUpTemplate
        {
            get { return m_mouseUpTemplate; }
            set
            {
                if (value != m_mouseUpTemplate)
                {
                    if (IsInitialized)
                    {
                        try
                        {
                            string workingString = value;
                            while (workingString.IndexOf("$targetname$") != -1)
                            {
                                workingString = workingString.Replace("$targetname$", this.Element.Name);
                            }
                            string genName = GenerateName(Plugin);
                            while (workingString.IndexOf("$name$") != -1)
                            {
                                workingString = workingString.Replace("$name$", genName);
                            }
                            m_mouseUpAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                            m_mouseUpTemplate = value;
                            Element.Resources.Add(m_mouseUpAnim);
                        }
                        catch
                        {
                            Debug.Trace("MouseDownTemplate_set failed");
                        }
                    }
                    else
                    {
                        m_mouseUpTemplate = value;
                    }
                }
            }
        }

        Storyboard m_mouseEnterAnim;
        protected Storyboard MouseEnterAnim
        {
            get { return m_mouseEnterAnim; }
        }
        Storyboard m_mouseLeaveAnim;
        protected Storyboard MouseLeaveAnim
        {
            get { return m_mouseLeaveAnim; }
        }
        Storyboard m_mouseDownAnim;
        protected Storyboard MouseDownAnim
        {
            get { return m_mouseDownAnim; }
        }
        Storyboard m_mouseUpAnim;
        protected Storyboard MouseUpAnim
        {
            get { return m_mouseUpAnim; }
        }

        private MouseEventHandler m_mouseEnterHandler;
        private MouseEventHandler m_mouseLeaveHandler;
        private MouseEventHandler m_mouseDownHandler;
        private MouseEventHandler m_mouseUpHandler;

        public Button()
        {
            

        }
        public override void Dispose()
        {
            m_mouseDownAnim = null;
            m_mouseEnterAnim = null;
            m_mouseLeaveAnim = null;
            m_mouseUpAnim = null;
            Element.RemoveEventListener(InputEvent.MouseEnter, m_mouseEnterHandler);
            Element.RemoveEventListener(InputEvent.MouseLeave, m_mouseLeaveHandler);
            Element.RemoveEventListener(InputEvent.MouseLeftButtonDown, m_mouseDownHandler);
            Element.RemoveEventListener(InputEvent.MouseLeftButtonUp, m_mouseUpHandler);

            m_mouseEnterHandler = null;
            m_mouseLeaveHandler = null;
            m_mouseDownHandler = null;
            m_mouseUpHandler = null;
            base.Dispose();
        }
        public override void Initialize()
        {            
            base.Initialize();
            if (!(bool)(object)m_mouseEnterName)
                m_mouseEnterName = ElementName + "_mouseEnter";
            if (!(bool)(object)m_mouseLeaveName)
                m_mouseLeaveName = ElementName + "_mouseLeave";
            if (!(bool)(object)m_mouseDownName)
                m_mouseDownName = ElementName + "_mouseDown";
            if (!(bool)(object)m_mouseUpName)
                m_mouseUpName = ElementName + "_mouseUp";
            #region anims initializing

            if ((bool)(object)m_mouseDownTemplate)
            {
                try
                {
                    string workingString = m_mouseDownTemplate;
                    while (workingString.IndexOf("$targetname$") != -1)
                    {
                        workingString = workingString.Replace("$targetname$", this.Element.Name);
                    }
                    string genName = GenerateName(Plugin);
                    while (workingString.IndexOf("$name$") != -1)
                    {
                        workingString = workingString.Replace("$name$", genName);
                    }
                    m_mouseDownAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                    Element.Resources.Add(m_mouseDownAnim);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse down");
                }
            }
            else
            {
                try
                {
                    m_mouseDownAnim = (Storyboard)Element.FindName(m_mouseDownName);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse down");
                }
            }

            if((bool)(object)m_mouseEnterTemplate)
            {
                try
                {
                    string workingString = m_mouseEnterTemplate;
                    while (workingString.IndexOf("$targetname$") != -1)
                    {
                        workingString = workingString.Replace("$targetname$", this.Element.Name);
                    }
                    string genName = GenerateName(Plugin);
                    while (workingString.IndexOf("$name$") != -1)
                    {
                        workingString = workingString.Replace("$name$", genName);
                    }
                    m_mouseEnterAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                    Element.Resources.Add(m_mouseEnterAnim);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse enter");
                }
            }
            else
            {
                try
                {
                    m_mouseEnterAnim = (Storyboard)Element.FindName(m_mouseEnterName);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse enter");
                }
            }


            if ((bool)(object)m_mouseLeaveTemplate)
            {
                try
                {
                    string workingString = m_mouseLeaveTemplate;
                    while (workingString.IndexOf("$targetname$") != -1)
                    {
                        workingString = workingString.Replace("$targetname$", this.Element.Name);
                    }
                    string genName = GenerateName(Plugin);
                    while (workingString.IndexOf("$name$") != -1)
                    {
                        workingString = workingString.Replace("$name$", genName);
                    }
                    m_mouseLeaveAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                    Element.Resources.Add(m_mouseLeaveAnim);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse leave");
                }
            }
            else
            {
                try
                {
                    m_mouseLeaveAnim = (Storyboard)Element.FindName(m_mouseLeaveName);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse leave");
                }
            }


            if ((bool)(object)m_mouseUpTemplate)
            {
                try
                {
                    string workingString = m_mouseUpTemplate;
                    while (workingString.IndexOf("$targetname$") != -1)
                    {
                        workingString = workingString.Replace("$targetname$", this.Element.Name);
                    }
                    string genName = GenerateName(Plugin);
                    while (workingString.IndexOf("$name$") != -1)
                    {
                        workingString = workingString.Replace("$name$", genName);
                    }
                    m_mouseUpAnim = (Storyboard)Plugin.Content.CreateFromXaml(workingString);
                    Element.Resources.Add(m_mouseUpAnim);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse up");
                }
            }
            else
            {
                try
                {
                    m_mouseUpAnim = (Storyboard)Element.FindName(m_mouseUpName);
                }
                catch
                {
                    Debug.Trace("Button:Initialize: no animation for mouse up");
                }
            }
            #endregion

            #region Event handling
            m_mouseEnterHandler = OnMouseEnter;
            m_mouseLeaveHandler = OnMouseLeave;
            m_mouseDownHandler = OnMouseDown;
            m_mouseUpHandler = OnMouseUp;

            Element.AddEventListener(InputEvent.MouseEnter, m_mouseEnterHandler);
            Element.AddEventListener(InputEvent.MouseLeave, m_mouseLeaveHandler);
            Element.AddEventListener(InputEvent.MouseLeftButtonDown, m_mouseDownHandler);
            Element.AddEventListener(InputEvent.MouseLeftButtonUp, m_mouseUpHandler);
            #endregion
        }
        private bool m_isMouseDown = false;
        public bool IsMouseDown
        {
            get { return m_isMouseDown; }
            set { m_isMouseDown = value; }
        }

        private bool m_isMouseInner = false;
        public bool IsMouseInner
        {
            get { return m_isMouseInner; }
            set { m_isMouseInner = value; }
        }
        
        protected virtual void OnMouseEnter(object sender, MouseEventArgs args)
        {
            Debug.Trace("Enter");
            m_isMouseInner = true;
            if (m_isMouseDown)
            {
                this.Element.CaptureMouse();
                if ((bool)(object)m_mouseDownAnim)
                {
                    m_mouseDownAnim.Begin();
                }

            }
            else
            {
                if ((bool)(object)m_mouseEnterAnim)
                {
                    m_mouseEnterAnim.Begin();
                }
            }
        }
        protected virtual void OnMouseLeave(object sender, MouseEventArgs args)
        {
            Debug.Trace("Leave");
            m_isMouseInner = false;
            if (m_isMouseDown)
            {
                if ((bool)(object)m_mouseUpAnim)
                {
                    m_mouseUpAnim.Begin();
                }
            }
            else
            {
                if ((bool)(object)m_mouseLeaveAnim)
                {
                    m_mouseLeaveAnim.Begin();
                }
            }
        }
        protected virtual void OnMouseDown(object sender, MouseEventArgs args)
        {
            Debug.Trace("Down");
            this.Element.CaptureMouse();
            m_isMouseDown = true;
            if ((bool)(object)m_mouseDownAnim)
            {
                m_mouseDownAnim.Begin();
            }
        }
        protected virtual void OnMouseUp(object sender, MouseEventArgs args)
        {
            Debug.Trace("Up");
            this.Element.ReleaseMouseCapture();
            if (this.m_isMouseInner)
            {
                RaiseEvent("click");
                if ((bool)(object)m_mouseUpAnim)
                {
                    m_mouseUpAnim.Begin();
                }
            }
            else
            {
                if ((bool)(object)m_mouseLeaveAnim)
                {
                    m_mouseLeaveAnim.Begin();
                }
            }
            m_isMouseDown = false;
        }
        public void add_click(EventHandler handler)
        {
            Events.AddHandler("click", handler);
        }
        public void remove_click(EventHandler handler)
        {
            Events.RemoveHandler("click",handler);
        }
    }
}